package com.itheima.service.impl;

import com.itheima.mapper.MemberMapper;
import com.itheima.mapper.OrderMapper;
import com.itheima.mapper.OrdersettingMapper;
import com.itheima.mapper.SetmealMapper;
import com.itheima.pojo.*;
import com.itheima.service.OrdersettingService;
import com.itheima.service.ReportService;
import io.swagger.models.auth.In;
import org.apache.poi.xssf.usermodel.XSSFCell;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.time.DayOfWeek;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.time.temporal.TemporalAdjusters;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;

@Service
public class ReportServiceImpl implements ReportService {

    @Autowired
    private MemberMapper memberMapper;
    @Autowired
    private OrderMapper orderMapper;
    @Autowired
    private SetmealMapper setmealMapper;
    @Autowired
    private OrdersettingMapper ordersettingMapper;

    @Override
    public SetmealReport getSetmealReport() {
        SetmealReport result = new SetmealReport();
        List<String> nameList = new ArrayList<>();
        List<SetmealValue> setmealValues = new ArrayList<>();
        //获取预约情况
        List<Order> orderList = orderMapper.getOrderList();
        for (Order order : orderList) {
            //根据id去获取套餐的名字
            String name = setmealMapper.getNameById(order.getSetmealId()).get(0);
            //匹配封装
            SetmealValue setmealValue =new SetmealValue(name,order.getCount());
            nameList.add(name);
            setmealValues.add(setmealValue);
        }
        result.setSetmealNames((ArrayList<String>) nameList);
        result.setSetmealCount((ArrayList<SetmealValue>) setmealValues);
        return result;
    }

    //用于传入运营统计sql语句中判断进行如何的取值
    private static final Integer TODAY = 1;
    private static final Integer THIS_WEEK= 2;
    private static final Integer THIS_MONTH = 3;

    /**
     * 获取运营统计数据
     * @return
     */
    @Override
    public BusinessReportData getBusinessReportData() {
        BusinessReportData result = new BusinessReportData();
        //加载下载日期
        result.setReportDate(LocalDate.now());
        //会员数统计
        result.setTotalMember(memberMapper.getTotalMember());
        result.setTodayNewMember(newMember(TODAY));
        result.setThisWeekNewMember(newMember(THIS_WEEK));
        result.setThisMonthNewMember(newMember(THIS_MONTH));

        //预约数统计
        result.setTodayOrderNumber(orderCount(TODAY));
        result.setThisWeekOrderNumber(orderCount(THIS_WEEK));
        result.setThisMonthOrderNumber(orderCount(THIS_MONTH));

        //到诊数统计
        result.setTodayVisitsNumber(visitsCount(TODAY));
        result.setThisWeekVisitsNumber(visitsCount(THIS_WEEK));
        result.setThisMonthVisitsNumber(visitsCount(THIS_MONTH));

        //热门套餐统计
        SetmealReport setmealReport = getSetmealReport();
        Integer total = ordersettingMapper.getTotalCount();
        ArrayList<HotSetmeal> hotSetmealList = new ArrayList<>();
        setmealReport.getSetmealCount().sort(new Comparator<SetmealValue>() {
            @Override
            public int compare(SetmealValue o1, SetmealValue o2) {
                if(o1.getValue() > o2.getValue())
                return 1;
                else
                    return -1;
            }
        });
        //找最大的四个
        for (int i = 0; i < 4; i++) {
            HotSetmeal hotSetmeal = new HotSetmeal();
            hotSetmeal.setName(setmealReport.getSetmealNames().get(i));
            hotSetmeal.setSetmeal_count(setmealReport.getSetmealCount().get(i).getValue());
            hotSetmeal.setProportion((double) (setmealReport.getSetmealCount().get(i).getValue()/total));

            hotSetmealList.add(hotSetmeal);
        }
        result.setHotSetmeal(hotSetmealList);
        return result;
    }

    /**
     * 导出运营数据到Excel并提供客户端下载
     */
    @Override
    public void exportBusinessReport(HttpServletResponse response) {
        //查询数据
        BusinessReportData data = getBusinessReportData();
        //查询到的数据通过poi写入到excel文件中
        response.setCharacterEncoding("UTF-8");
        response.setContentType("application/vnd.ms-excel;charset=UTF-8");
        response.setHeader("Content-Disposition","attachment:filename=" + "运营数据统计");
        InputStream stream = this.getClass().getClassLoader().getResourceAsStream("templates/report_template.xlsx");

        try {
            XSSFWorkbook excel = new XSSFWorkbook(stream);

            //填充数据
            XSSFSheet sheet1 = excel.getSheet("Sheet1");

            //填充日期
            XSSFRow row1 = sheet1.getRow(2);

            XSSFCell cell1 = row1.getCell(5);

            cell1.setCellValue(data.getReportDate().toString());

            //填充会员数据
            row1 = sheet1.getRow(4);

            cell1 = row1.getCell(5);

            cell1.setCellValue(data.getTodayNewMember());

            cell1 = row1.getCell(7);

            cell1.setCellValue(data.getTotalMember());

            row1 = sheet1.getRow(5);

            cell1 = row1.getCell(5);

            cell1.setCellValue(data.getThisWeekNewMember());

            cell1 = row1.getCell(7);

            cell1.setCellValue(data.getThisMonthNewMember());

            //填充预约到诊数据
            row1 = sheet1.getRow(7);

            cell1 = row1.getCell(5);

            cell1.setCellValue(data.getTodayOrderNumber());

            cell1 = row1.getCell(7);

            cell1.setCellValue(data.getTodayVisitsNumber());

            row1 = sheet1.getRow(8);

            cell1 = row1.getCell(5);

            cell1.setCellValue(data.getThisWeekOrderNumber());

            cell1 = row1.getCell(7);

            cell1.setCellValue(data.getThisWeekVisitsNumber());

            row1 = sheet1.getRow(9);

            cell1 = row1.getCell(5);

            cell1.setCellValue(data.getThisMonthOrderNumber());

            cell1 = row1.getCell(7);

            cell1.setCellValue(data.getThisMonthVisitsNumber());

            ArrayList<HotSetmeal> hotSetmeal = data.getHotSetmeal();

            //填充热门套餐数据
            for (int i = 0; i < 4; i++) {
                row1 = sheet1.getRow(12+i);

                cell1 = row1.getCell(4);

                cell1.setCellValue(hotSetmeal.get(i).getName());

                cell1 = row1.getCell(5);

                cell1.setCellValue(hotSetmeal.get(i).getSetmeal_count());

                cell1 = row1.getCell(6);

                cell1.setCellValue(hotSetmeal.get(i).getProportion());

            }

            //通过输出流excel文件下载到客户端浏览器
            ServletOutputStream out = response.getOutputStream();
            excel.write(out);
            out.close();
            excel.close();
        } catch (IOException e) {
            throw new RuntimeException(e);
        }

    }

    /**
     * 获取相应日期内的到诊数
     * @param method
     * @return
     */
    private Integer visitsCount(Integer method) {
        Integer result = 0;
        switch (method){
            case 1:{
                result = orderMapper.getVisitsCount(LocalDate.now(),LocalDate.now());
            }
            case 2:{
                result = orderMapper.getVisitsCount(LocalDate.now().with(DayOfWeek.MONDAY),LocalDate.now().with(DayOfWeek.SUNDAY));
            }
            case 3: {
                result = orderMapper.getVisitsCount(LocalDate.now().with(TemporalAdjusters.firstDayOfMonth()),LocalDate.now().with(TemporalAdjusters.lastDayOfMonth()));
            }

        }
        return result;
    }

    /**
     * 获取相应日期内的预约数
     * @param method
     * @return
     */
    private Integer orderCount(Integer method) {
        Integer result = 0;
        switch (method){
            case 1:{
                result = ordersettingMapper.getOrderCount(LocalDate.now(),LocalDate.now());
            }
            case 2:{
                result = ordersettingMapper.getOrderCount(LocalDate.now().with(DayOfWeek.MONDAY),LocalDate.now().with(DayOfWeek.SUNDAY));
            }
            case 3: {
                result = ordersettingMapper.getOrderCount(LocalDate.now().with(TemporalAdjusters.firstDayOfMonth()),LocalDate.now().with(TemporalAdjusters.lastDayOfMonth()));
            }

        }
        return result;
    }

    /**
     *获取相应日期内的新增会员数
     * @param method
     * @return
     */
    private Integer newMember(Integer method) {
        Integer result = 0;
        switch (method){
            case 1:{
                result = memberMapper.getNewMember(LocalDate.now(),LocalDate.now());
            }
            case 2:{
                result = memberMapper.getNewMember(LocalDate.now().with(DayOfWeek.MONDAY),LocalDate.now().with(DayOfWeek.SUNDAY));
            }
            case 3: {
                result = memberMapper.getNewMember(LocalDate.now().with(TemporalAdjusters.firstDayOfMonth()),LocalDate.now().with(TemporalAdjusters.lastDayOfMonth()));
            }

        }
        return result;
    }

    /**
     * 获取会员数量统计数据
     * @return
     */
    @Override
    public MemberReport getMemberReport() {
        MemberReport result = new MemberReport();
        //获取日期
        List<LocalDate> dateList= memberMapper.getMemberReport();
        //格式转化与计数
        String date = new String();
        List<String> months = new ArrayList<>();
        List<Integer> memberCount = new ArrayList<>();
        for (LocalDate localDate : dateList) {
        int i = 0;
            //格式转化
            date = localDate.format(DateTimeFormatter.ofPattern("yyyy.MM.dd"));
            //count
            for (i = 0; i < memberCount.size(); i++) {
                //已经在里面存过该日期
                if (months.get(i).equals(date)) {
                    memberCount.set(i,(Integer)memberCount.get(i) + 1);
                    break;
                }
            }
                //没找到
                if(i >= memberCount.size()){
                    memberCount.add(1);
                }
            months.add(date);
        }
        //设置参数
        result.setMemberCount((ArrayList<Integer>) memberCount);
        result.setMonths((ArrayList) months);
        return result;
    }
}
